﻿using Microsoft.EntityFrameworkCore.ChangeTracking;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Fast.Extensions.DatabaseAccessor.EntityFrameworkCore
{
    /// <summary>
    /// 插入仓储实现
    /// </summary>
    public partial class RootRepository<TEntity>
        where TEntity : class, IRootEntity, new()
    {
        /// <summary>
        /// 新增一条记录
        /// </summary>
        /// <param name="entity">实体</param>
        public virtual void Insert(TEntity entity)
        {
            Entities.Add(entity);
        }
        /// <summary>
        /// 新增一条记录并返回带跟踪信息的实体
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>带跟踪信息的实体</returns>
        public virtual EntityEntry<TEntity> InsertWithReturnEntity(TEntity entity)
        {
            var entityEntry = Entities.Add(entity);

            return entityEntry;
        }
        /// <summary>
        /// 新增多条记录
        /// </summary>
        /// <param name="entities">多个实体</param>
        public virtual void Insert(IEnumerable<TEntity> entities)
        {
            Entities.AddRange(entities);
        }
        /// <summary>
        /// 新增一条记录并立即提交
        /// </summary>
        /// <param name="entity">实体</param>
        public virtual void InsertAndCommit(TEntity entity)
        {
            this.Insert(entity);

            SaveChanges();
        }
        /// <summary>
        /// 新增一条记录并立即提交,返回带跟踪信息的实体
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>数据库中返回的带跟踪信息的实体</returns>
        public virtual EntityEntry<TEntity> InsertAndCommitWithReturnEntity(TEntity entity)
        {
            var entityEntry = this.InsertWithReturnEntity(entity);

            SaveChanges();

            return entityEntry;
        }
        /// <summary>
        /// 新增多条记录并立即提交
        /// </summary>
        /// <param name="entities">多个实体</param>
        public virtual void InsertAndCommit(IEnumerable<TEntity> entities)
        {
            this.Insert(entities);

            SaveChanges();
        }
        /// <summary>
        /// 新增一条记录
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="cancellationToken">取消异步令牌</param>
        /// <returns>Task</returns>
        public virtual async Task InsertAsync(TEntity entity, CancellationToken cancellationToken = default)
        {
            await Entities.AddAsync(entity, cancellationToken);
        }
        /// <summary>
        /// 新增一条记录并返回带跟踪信息实体
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="cancellationToken">取消异步令牌</param>
        /// <returns>带跟踪信息实体</returns>
        public virtual async Task<EntityEntry<TEntity>> InsertWithReturnEntityAsync(TEntity entity, CancellationToken cancellationToken = default)
        {
            var entityEntry = await Entities.AddAsync(entity, cancellationToken);

            return entityEntry;
        }
        /// <summary>
        /// 新增多条记录
        /// </summary>
        /// <param name="entities">多个实体</param>
        /// <param name="cancellationToken">取消异步令牌</param>
        /// <returns></returns>
        public virtual async Task InsertAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
        {
            await Entities.AddRangeAsync(entities, cancellationToken);
        }
        /// <summary>
        /// 新增一条记录并立即提交
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="cancellationToken">取消异步令牌</param>
        public virtual async Task InsertAndCommitAsync(TEntity entity, CancellationToken cancellationToken = default)
        {
            await this.InsertAsync(entity, cancellationToken);
        }
        /// <summary>
        /// 新增一条记录并立即提交,返回带跟踪信息的实体
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="cancellationToken">取消异步令牌</param>
        /// <returns>数据库中返回的带跟踪信息的实体</returns>
        public virtual async Task<EntityEntry<TEntity>> InsertAndCommitWithReturnEntityAsync(TEntity entity, CancellationToken cancellationToken = default)
        {
            var entityEntry = await this.InsertWithReturnEntityAsync(entity, cancellationToken);

            await SaveChangesAsync(cancellationToken);

            return entityEntry;
        }
        /// <summary>
        /// 新增多条记录并立即提交
        /// </summary>
        /// <param name="entities">多个实体</param>
        /// <param name="cancellationToken">取消异步令牌</param>
        public virtual async Task InsertAndCommitAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default)
        {
            await this.InsertAsync(entities, cancellationToken);

            await SaveChangesAsync(cancellationToken);
        }
    }
}
